// 题目描述：给定一组不含重复元素的整数数组 nums，返回该数组所有可能的子集（幂集）。
// 说明：解集不能包含重复的子集。
/**
 * 示例: 输入: nums = [1,2,3]
输出:
[
[3],
[1],
[2],
[1,2,3],
[1,3],
[2,3],
[1,2],
[]
]
 */
/**
 * 思路分析：
 * 穷举出现了，大概率会用到 DFS。只要用到 DFS，就不得不想到树形思维方式，进而不得不思考递归式和递归边界的问题。
 * 
 * “坑位”对应的就是树形逻辑中树的某一层，“坑位数”往往意味着递归边界的限制条件。
 *    
 * 在这道题中，每个组合中数字的个数是不确定的，不变的东西变成了可以参与组合的数字，变化的东西则是每个数字在组合中的存在性。
 * 因此我们的思路可以调整为，从每一个数字入手，讨论它出现或者不出现的情况。
 * 
 * 1. 递归式：检查手里剩下的数字有哪些（有没有发现和上一道题的递归式是一样的，因为两道题都强调了数字不能重复使用），
 * 选取其中一个填进当前的坑里、或者干脆把这个坑空出来（这里就体现出了和上一道题的区别，这道题强调的是存在性而非顺序）
 * 2. 递归边界：组合里数字个数的最大值。拿示例来说，只给了 3 个数，因此组合里数字最多也只有 3 个，超过 3 个则视为触碰递归边界。  
 */

// 入参是一个数组
const subsets = function(nums) {
	// 初始化结果数组
	const res = [];
	// 缓存数组长度
	const len = nums.length;
	// 初始化组合数组
	const subset = [];
	// 进入 dfs
	dfs(0);

	// 定义 dfs 函数，入参是 nums 中的数字索引
	function dfs(index) {
		// 每次进入，都意味着组合内容更新了一次，故直接推入结果数组
		res.push(subset.slice());
		// 从当前数字的索引开始，遍历 nums
		for (let i = index; i < len; i++) {
			// 这是当前数字存在于组合中的情况
			subset.push(nums[i]);
			// 基于当前数字存在于组合中的情况，进一步 dfs
			dfs(i + 1);
			// 这是当前数字不存在与组合中的情况
			subset.pop();
		}
	}
	// 返回结果数组
	return res;
};
console.log(subsets([1,2,3]));
